package utils.json;

import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Map;

import utils.bean.ObjectUtils;
import utils.reflect.ClassUtils;

public final class JsonUtils {

	private JsonUtils() {

	}

	public static String convert(Object obj) {
		if (ObjectUtils.isNull(obj))
			return "{}";
		try{
			if (!ClassUtils.isJDKClass(obj.getClass())) {
				return convertBean(obj);
			} else if (obj instanceof Map) {
				return convertMap(obj);
			} else if (obj instanceof List) {
				return convertList(obj);
			} else if (obj.getClass().isArray()){
				return convertArray(obj);
			} 
			else {
				return "'" + obj.toString() + "'";
			}
		}catch (Exception e) {
			e.printStackTrace();
		}
		return "{}";
	}

	@SuppressWarnings("unchecked")
	private static String convertMap(Object map) {
		StringBuffer sb = new StringBuffer();
		Map<Object, Object> _map = (Map<Object, Object>) map;
		sb.append("{");
		for (Object key : _map.keySet()) {
			Object value = _map.get(key);
			if (ObjectUtils.isNotNull(value)) {
				sb.append(key);
				sb.append(":");
				sb.append(convertValue(value));
				sb.append(",");
			}
		}
		if(_map.size() > 0){
			sb.deleteCharAt(sb.length() - 1);
		}
		sb.append("}");
		return sb.toString();
	}

	@SuppressWarnings("unchecked")
	private static String convertList(Object list) {
		StringBuffer sb = new StringBuffer();
		List _list = (List) list;
		sb.append("[");
		for (Object object : _list) {
			if (ObjectUtils.isNotNull(object)) {
				sb.append(convertValue(object));
				sb.append(",");
			}
		}
		if(_list.size() > 0){
			sb.deleteCharAt(sb.length() - 1);
		}
		sb.append("]");
		return sb.toString();
	}
	
	private static String convertArray(Object array){
		StringBuffer sb = new StringBuffer();
		int length = Array.getLength(array);
		sb.append("[");
		for(int i = 0 ; i < length ; i++){
			Object value = Array.get(array, i);
			sb.append(convertValue(value));
			sb.append(",");
		}
		if(length > 0){
			sb.deleteCharAt(sb.length() - 1);
		}
		sb.append("]");
		return sb.toString();
	}

	@SuppressWarnings("unchecked")
	private static String convertBean(Object obj) throws SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException{
		StringBuffer sb = new StringBuffer();
		Class clz = obj.getClass();
		Field[] fields = clz.getDeclaredFields();
		sb.append("{");
		for(Field field : fields){
			String name = field.getName();
			Class type = field.getType();
			String tag = type.equals(boolean.class)? "is" : "get";
			String method = tag + name.substring(0,1).toUpperCase() + name.substring(1);
			Method _method = clz.getMethod(method);
			Object value = _method.invoke(obj);
			if (ObjectUtils.isNotNull(value)) {
				sb.append(name);
				sb.append(":");
				sb.append(convertValue(value));
				sb.append(",");
			}
		}
		if(fields.length > 0){
			sb.deleteCharAt(sb.length() - 1);
		}
		sb.append("}");
		return sb.toString();
	}
	
	private static String convertValue(Object value){
		if (Long.class.equals(value.getClass())
				|| Integer.class.equals(value.getClass())
				|| Double.class.equals(value.getClass())
				|| Boolean.class.equals(value.getClass())
				|| int.class.equals(value.getClass())
				|| long.class.equals(value.getClass())
				|| double.class.equals(value.getClass())
				|| boolean.class.equals(value.getClass())) {
			return value.toString();
		}else if(String.class.equals(value.getClass())){
			String _value = value.toString().replaceAll("\\'", "\\\\'");
			_value = "'" + _value + "'";
			return _value;
		}else {
			return convert(value);
		}
	}
}
